/* 
 * File:   JRepository.cpp
 * Author: johnneyshi
 * 
 * Created on 2013年1月6日, 上午8:57
 */

#include "JRepository.h"
#include "JDir.h"
#include "JUuid.h"
#include "JRepositoryConfig.h"
#include "JDefine.h"
#include "JInOutPutFstream.h"
#include "Convert.h"
#include "JVerifyValidate.h"
#include <string>
#include <pthread.h>

//pthread_rwlock_t JRepository::rwlock_t;
//pthread_rwlockattr_t JRepository::rwlock_arrt_t;

JRepositoryOperationResult JRepository::GetLock(std::string lockType)
{
    ReadFromFile();
    //表示要写，此时应该新建一个版本
    if(lockType == "write")
    {
        CreateAVersion();
    }
    //表示是读
    else
    {
        
    }
    JRepositoryOperationResult result;
    return result;
}

JRepository::JRepository():isReposModify(false)
{
    
}

JRepository::~JRepository()
{

}

JRepositoryOperationResult JRepository::ReleaseLock()
{
    WriteToFile();
    JRepositoryOperationResult result;
    return result;
}
    
JRepositoryOperationResult JRepository::Add(JFile& _file)
{
    return listPVersionRepos.front()->Add(_file);
}

JRepositoryOperationResult JRepository::Add(JDir& _dir)
{
    return listPVersionRepos.front()->Add(_dir);
}
    
JRepositoryOperationResult JRepository::Delete(JFile& _file)
{
    return listPVersionRepos.front()->Delete(_file);
}

JRepositoryOperationResult JRepository::Delete(JDir& _dir)
{
    return listPVersionRepos.front()->Delete(_dir);
}

    
JRepositorySearchResult JRepository::Search(string _fileName,int _versionID)
{
    if(_versionID == -1)
    {
        _versionID = currentVersionID;
    }
    OpenAVersion(_versionID);
    return listPVersionRepos.front()->Search(_fileName);
}
    
JRepositoryOperationResult JRepository::Modify(JFile& _file1,JFile& _file2)
{
    return listPVersionRepos.front()->Modify(_file1,_file2);
}
JRepositoryOperationResult JRepository::Modify(JDir& _dir1,JDir& _dir2)
{
    return listPVersionRepos.front()->Modify(_dir1,_dir2);
}

int JRepository::Serialize(JInOutPut& strea,int& allSize)
{
    int classSize = 0,selfSize = 0;
    JSerialize::SerializeHead(strea,selfSize,classSize);
    JSerialize::Serialize(strea,currentVersionID,classSize);
    return JSerialize::SerializeTail(strea,allSize,selfSize,classSize);
}

int JRepository::ReSerialize(JInOutPut& strea)
{
    int classSize = JSerialize::ReSerializeHead(strea);
    currentVersionID = JSerialize::ReSerializeInt(strea);
    return classSize;
}


JRepositoryOperationResult JRepository::CreateAVersion()
{
    JVersionRepository* pVersionRepos = new JVersionRepository();
    pVersionRepos->CreateAVersion(++currentVersionID);
    listPVersionRepos.push_back(pVersionRepos);
    isReposModify = true;
    JRepositoryOperationResult result;
    return result;
}

JRepositoryOperationResult JRepository::OpenAVersion(int _versionID)
{
    JVersionRepository* pVersionRepos = new JVersionRepository();
    pVersionRepos->ReadTheVersion(_versionID);
    listPVersionRepos.push_back(pVersionRepos);
    isReposModify = false;
    JRepositoryOperationResult result;
    return result;
}

void JRepository::ReadFromFile()
{
        //反序列化
    std::string rootPath = JRepositoryConfig::repositoryRootPath;
    std::string fileName = rootPath + PATH_SPLIT + "RepositoryInfo";
    if(JFile::IsExist(fileName))
    {
        JInOutPutFstream strea(fileName);
        strea.OpenStream(ios::binary | ios::in);
        ReSerialize(strea);
    }
    else
    {
        currentVersionID = -1;
    }
}

void JRepository::WriteToFile()
{
        //序列化Repository
    std::string rootPath = JRepositoryConfig::repositoryRootPath;
    std::string fileName = rootPath + PATH_SPLIT + "RepositoryInfo";
    if(!JFile::IsExist(fileName))
    {
        JFile::CreateFile(fileName);
    }
    JInOutPutFstream strea(fileName);
    strea.OpenStream(ios::binary | ios::trunc | ios::out);
    int allSize;
    Serialize(strea,allSize);
    //序列化VersionRepository
    if(isReposModify == true)
    {
        listPVersionRepos.front()->InitiativeSerialize();
    }
}